package ma.ensao.egicom.bank.services.implementation;

import static ma.ensao.egicom.bank.services.utils.AccountKeyUtils.ACCOUNT_NUMBER_TAG;
import static ma.ensao.egicom.bank.services.utils.CreditCardKeyUtils.CARD_CVC_TAG;
import static ma.ensao.egicom.bank.services.utils.CreditCardKeyUtils.CARD_EXPIRATION_DATE_TAG;
import static ma.ensao.egicom.bank.services.utils.CreditCardKeyUtils.CARD_NUMBER_TAG;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ma.ensao.egicom.bank.services.BankServices;
import ma.ensao.egicom.bank.services.dao.interfaces.AccountDao;
import ma.ensao.egicom.bank.services.dao.interfaces.CreditCardDao;
import ma.ensao.egicom.bank.services.dao.interfaces.OperationDao;
import ma.ensao.egicom.bank.services.dto.CreditCardDto;
import ma.ensao.egicom.bank.services.model.Account;
import ma.ensao.egicom.bank.services.model.CreditCard;
import ma.ensao.egicom.bank.services.model.Operation;
import ma.ensao.egicom.bank.services.utils.OperationType;

/**
 * Implementation des services qui permettent de réaliser des transactions bancaires.
 * @author MILHI Yassine (milhi.yassinee@gmail.Com)
 */
public class BankServicesImpl implements BankServices {

    private AccountDao accountDao;

    private CreditCardDao creditCardDao;

    private OperationDao operationDao;

    private void creditOrDebitAccount(Account account, OperationType opType, double commandCost) {

        commandCost = commandCost * (opType == OperationType.CREDITER ? 1 : -1);
        account.setBalance(account.getBalance() + commandCost);
        accountDao.updateAccountBalance(account);
    }

    @Override
    public String doTransaction(double commandCost, CreditCardDto cardDto, String RIBSupplier) {

        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(CARD_NUMBER_TAG, cardDto.getCardNumber());
        properties.put(CARD_EXPIRATION_DATE_TAG, cardDto.getExprationDate());
        properties.put(CARD_CVC_TAG, cardDto.getCvc());
        // TODO verify compleName

        CreditCard creditCard = creditCardDao.getCreditCardByProperties(properties);
        Account clientAccount = creditCard.getAccount();
        creditOrDebitAccount(clientAccount, OperationType.DEBITER, commandCost);
        List<Account> supplierAccount = accountDao.getAccountByProperty(ACCOUNT_NUMBER_TAG, RIBSupplier);
        creditOrDebitAccount(supplierAccount.get(0), OperationType.CREDITER, commandCost);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        
        Operation operationClient = new Operation(calendar, commandCost, OperationType.DEBITER,creditCard);
        operationDao.createOperation(operationClient);

        Operation operationSupplier = new Operation(calendar, commandCost, OperationType.CREDITER,creditCard);
        operationDao.createOperation(operationSupplier);

        return "Transaction success";
    }
}
